<!DOCTYPE html>
<html lang="zh-cn">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<script>
    /**
     <canvas id='canvas' width='500' height='500'></canvas>
     [注]
     设置canvas的宽高要在元素或在其API，canvas.width || canvas.height，在CSS上设置为得到意想不到的结果，不信试试看哈···

     //demo.js
     var canvas = document.getElementById('canvas');
     var context = canvas.getContext('2d');

     //路径或图形
     context.fillRect();//填充矩形
     context.strokeRect();//勾勒矩形轮廓
     context.arc(x,y,r,anglestart,angleend,clockwise);//画弧形

     context.beginPath();//开始路径
     context.moveTo();//定义路径起始点
     context.lineTo();//路径的去向
     context.closePath();//画完后，关闭路径
     context.fill() || context.stroke();//最后画出由路径构成的图形
     [注]
     本质上，所有的多边形都可以由路径画出；

     context.save();//保存save以上context对象设置的属性值
     context.restore();//恢复到先前保存在context对象上的所有属性值

     */
</script>
<script>
    class Ball {
        constructor() {
            this.x = 0;
            this.y = 0;
            this.r = 50;
            this.rotation = 0;
            this.scaleX = 1;
            this.scaleY = 1
            this.color = 'red'
        }
        draw(context){
            context.save();
            context.translate(this.x,this.y);
            context.rotate(this.rotation);
            context.scale(this.scaleX,this.scaleY);
            context.fillStyle = this.color;
            context.beginPath();
            context.arc(0,0,this.r,0,2*Math.PI,true);
            context.closePath();
            context.fill();
            context.stroke();
            context.restore();
        }
    }

    class Arrow {
        constructor() {
            this.x = 0;
            this.y = 0;
            this.rotation = 0; // 旋转角度
            this.color = 'red'
        }
        draw(context){
            context.save();
            context.translate(this.x,this.y);
            context.rotate(this.rotation);
            context.lineWidth = 5;
            context.fillStyle = this.color;
            context.beginPath();
            context.moveTo(-50,-25);
            context.lineTo(0,-25);
            context.lineTo(0,-50);
            context.lineTo(50,0);
            context.lineTo(0,50);
            context.lineTo(0,25);
            context.lineTo(-50,25);
            context.lineTo(-50,25);
            context.closePath();
            context.stroke();
            context.fill();
            context.restore();
        }
    }
</script>
<!--线性运动-->
<!--<canvas id="canvas01" width="500" height="500" style="background: #000"></canvas>
<script>
    let canvas01 = document.getElementById('canvas01');
    (function drawFrame({width,height,context,ball,xspeed}){
        window.requestAnimationFrame(() => drawFrame({width,height,context,ball,xspeed}));
        context.clearRect(0,0,width,height);

        ball.x += xspeed;
        ball.y = height/2;

        if(ball.x>width+ball.r){
            ball.x = -ball.r;
        }

        ball.draw(context);
    })({
        width:canvas01.width,
        height:canvas01.height,
        context:canvas01.getContext('2d'),
        ball:new Ball(),
        xspeed:1
    });
</script>-->

<!--加速运动-->
<!--<canvas id="canvas02" width="500" height="500" style="background: #000"></canvas>
<script>
    let canvas02 = document.getElementById('canvas02');

    (function drawFrame({width,height,context,ball,xspeed,ax}){
        window.requestAnimationFrame(() => drawFrame({width,height,context,ball,xspeed,ax}));
        context.clearRect(0,0,width,height);

        ball.x += xspeed;

        ball.y = height/2;
        xspeed += ax;
        if(ball.x>width+ball.r){
            ball.x = -ball.r;
        }

        ball.draw(context);
    })({
        width:canvas02.width,
        height:canvas02.height,
        context:canvas02.getContext('2d'),
        ball:new Ball(),
        xspeed:1,
        ax: 0.5
    });
</script>-->

<!--自由落体-->
<!--<canvas id="canvas03" width="500" height="500" style="background: #000"></canvas>
<script>
    let canvas03 = document.getElementById('canvas03');
    (function drawFrame({width,height,context,ball,vy,gravity,bounce}){
        window.requestAnimationFrame(() => drawFrame({width,height,context,ball,vy,gravity,bounce}));
        context.clearRect(0,0,width,height);

        ball.x = width/2;
        //小球首先做向下的加速运动
        vy += gravity;
        ball.y += vy;

        // 碰撞判断
        if(ball.y+ball.r>height){
            //小球碰到地面时，让球的位置暂时设置为在地面上
            ball.y = height - ball.r;
            //此时设置小球落到地面时的速度为反向，大小为原来的0.8；
            vy *= bounce;
        }

        ball.draw(context);
    })({
        width:canvas03.width,
        height:canvas03.height,
        context:canvas03.getContext('2d'),
        ball:new Ball(),
        vy:0, // 垂直方向初速度
        gravity: 0.1, // 定义重力加速度
        bounce:-0.8, // 反弹系数
    });
</script>-->

<!--波形运动-->
<!--<canvas id="canvas04" width="500" height="500" style="background: #000"></canvas>
<script>
    let canvas04 = document.getElementById('canvas04');
    (function drawFrame({width,height,context,ball,angle,swing}){
        window.requestAnimationFrame(() => drawFrame({width,height,context,ball,angle,swing}));
        context.clearRect(0,0,width,height);

        ball.x += 2;
        ball.y = height/2+Math.sin(angle)*swing;
        angle += 0.1;

        if(ball.x>width+ball.r){
            ball.x = -ball.r;
        }

        ball.draw(context);
    })({
        width:canvas04.width,
        height:canvas04.height,
        context:canvas04.getContext('2d'),
        ball:new Ball(),
        angle:0, // 角度
        swing: 100, // 振幅
    });
</script>-->
<!--圆形运动-->
<!--<canvas id="canvas05" width="500" height="500" style="background: #000"></canvas>
<script>
    let canvas05 = document.getElementById('canvas05');
    (function drawFrame({width,height,context,ball,angle,scope}){
        window.requestAnimationFrame(() => drawFrame({width,height,context,ball,angle,scope}));
        context.clearRect(0,0,width,height);

        ball.x = width/2+Math.cos(angle)*scope;
        ball.y = height/2+Math.sin(angle)*scope;
        angle += 0.1;

        ball.draw(context);
    })({
        width:canvas05.width,
        height:canvas05.height,
        context:canvas05.getContext('2d'),
        ball:new Ball(),
        angle:0, // 角度
        scope: 100, // 旋转半径
    });
</script>-->

<!--椭圆运动-->
<!--<canvas id="canvas06" width="500" height="500" style="background: #000"></canvas>
<script>
    let canvas06 = document.getElementById('canvas06');
    (function drawFrame({width,height,context,ball,angle,scopeX,scopeY}){
        window.requestAnimationFrame(() => drawFrame({width,height,context,ball,angle,scopeX,scopeY}));
        context.clearRect(0,0,width,height);

        ball.x = width/2+Math.cos(angle)*scopeX;
        ball.y = height/2+Math.sin(angle)*scopeY;
        angle += 0.1;

        ball.draw(context);
    })({
        width:canvas06.width,
        height:canvas06.height,
        context:canvas06.getContext('2d'),
        ball:new Ball(),
        angle:0, // 角度
        scopeX: 150, // 旋转X半径
        scopeY: 80, // 旋转Y半径
    });
</script>-->

<!--自转-->
<!--<canvas id="canvas07" width="500" height="500" style="background: #000"></canvas>
<script>
    let canvas07 = document.getElementById('canvas07');
    (function drawFrame({width,height,context,arrow,angle}){
        window.requestAnimationFrame(() => drawFrame({width,height,context,arrow,angle}));
        context.clearRect(0,0,width,height);

        arrow.x = width/2;
        arrow.y = height/2;
        arrow.rotation = angle;
        angle +=0.1;

        arrow.draw(context);
    })({
        width:canvas07.width,
        height:canvas07.height,
        context:canvas07.getContext('2d'),
        arrow:new Arrow(),
        angle:0, // 角度
    });
</script>-->

<!--跟随鼠标转动-->
<canvas id="canvas08" width="500" height="500" style="background: #000"></canvas>
<script>
    let canvas08 = document.getElementById('canvas08');
    // 监听鼠标相对于元素移动位置
    function captureMouse(element) {
        let mouse = {
            x: 0,
            y: 0
        };

        element.addEventListener('mousemove', function(event) {
            let x, y;
            if (event.pageX || event.pageY) {
                x = event.pageX;
                y = event.pageY;
            } else {
                x = event.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
                y = event.clientY + document.body.scrollTop + document.documentElement.scrollTop;
            }

            let Box = element.getBoundingClientRect();

            x = (x - Box.left) * (element.width / Box.width);
            y = (y - Box.top) * (element.height / Box.height);

            mouse.x = x;
            mouse.y = y;
        }, false);

        return mouse;
    }
    (function drawFrame({width,height,context,arrow,angle,mouse}){
        window.requestAnimationFrame(() => drawFrame({width,height,context,arrow,angle,mouse}));
        context.clearRect(0,0,width,height);

        arrow.x = width/2;
        arrow.y = height/2;
        let dx = mouse.x - arrow.x;
        let dy = mouse.y - arrow.y;
        angle = Math.atan2(dy,dx);
        arrow.rotation = angle;

        arrow.draw(context);
    })({
        width:canvas08.width,
        height:canvas08.height,
        context:canvas08.getContext('2d'),
        arrow:new Arrow(),
        angle:0, // 角度
        mouse: captureMouse(canvas08)
    });
</script>

<!--缩放比例-->
<!--<canvas id="canvas09" width="500" height="500" style="background: #000"></canvas>
<script>
    let canvas09 = document.getElementById('canvas09');
    (function drawFrame({width,height,context,ball,angle,centerScale,swing}){
        window.requestAnimationFrame(() => drawFrame({width,height,context,ball,angle,centerScale,swing}));
        context.clearRect(0,0,width,height);

        ball.x = width/2;
        ball.y = height/2;
        angle += 0.05

        ball.scaleX = ball.scaleY = centerScale + Math.sin(angle)*swing;

        ball.draw(context);
    })({
        width:canvas09.width,
        height:canvas09.height,
        context:canvas09.getContext('2d'),
        ball:new Ball(),
        angle:0, // 角度
        centerScale: 1,
        swing: 0.5
    });
</script>-->
</body>
</html>